/**
 * Project Name:payment
 * File Name:SignUtils.java
 * Package Name:cn.swiftpass.utils.payment.sign
 * Date:2014-6-27下午3:22:33
 */

package com.acooly.module.openapi.client.provider.shengpay.utils;

import com.acooly.core.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.util.Base64;


/**
 * ClassName:SignUtils
 * Function: 签名用的工具箱
 * Date:     2014-6-27 下午3:22:33
 *
 * @author
 */
@Slf4j
public class SignUtils {

    public final static String RSA_CHIPER = "RSA/ECB/PKCS1Padding";

    /**
     * 编码
     */
    public final static String ENCODE = "UTF-8";

    /**
     * 生成AES加密所需Key的算法 */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * 加解密算法/工作模式/填充方式,Java6.0支持PKCS5Padding填充方式,BouncyCastle支持PKCS7Padding填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 函数功能：敏感信息加密,AES算法为AES/CBC/PKCS5Padding
     * 参数：key，16位随机字符串
     * 参数：tobeEncoded，待加密的字符串，如银行卡号，V5版中的数字信封明文
     * 参数：iv,AES加密用到的IV值，V3，V4版本接口为固定值1234567892546398，V5版本接口随商户证书一起提供
     * * */

    public static String encode(String key,String tobeEncoded,String iv) {
        try {
            //1.AES加密
            Key k = new SecretKeySpec(key.getBytes(ENCODE), KEY_ALGORITHM);
            IvParameterSpec ivs = new IvParameterSpec(iv.getBytes());
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, k, ivs);
            byte[] bytes = cipher.doFinal(tobeEncoded.getBytes(ENCODE));
            //2.BASE64编码
            return new String(Base64.getEncoder().encode(bytes));
        }catch (Exception e) {
            log.info("AES加密失败:{}",e.getMessage());
            throw new BusinessException("AES加密失败"+e.getMessage());
        }
    }
    /**
     * 敏感信息解密，如银行卡等信息
     *
     * */

    public static String decode(String key,String tobeDecode,String iv) throws Exception{
        //BASE64解码
        byte[] base64Bytes=Base64.getDecoder().decode(tobeDecode);
        Key k =  new SecretKeySpec(key.getBytes(ENCODE), KEY_ALGORITHM);
        IvParameterSpec ivs = new IvParameterSpec(iv.getBytes());
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, k, ivs);
        byte[] bytes=cipher.doFinal(base64Bytes);
        return new String(bytes);

    }
    /**
     * 函数功能 :RSA非对称加密，用于对16位的AES秘钥进行加密,算法为RSA/ECB/PKCS1Padding
     * 参数：TobeEncryptMsg待加密的字符串，如16位AES秘钥
     * */

    public static String rsaEncode(String TobeEncryptMsg,PublicKey publicKey){
        //获取公钥
        Cipher instance;
        try {
            instance = Cipher.getInstance(RSA_CHIPER);
            instance.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] bytes=instance.doFinal(TobeEncryptMsg.getBytes());
            return new String(Base64.getEncoder().encode(bytes));
        } catch (Exception e) {
            throw new RuntimeException("RSA加密失败", e);
        }

    }

    /**
     * 盛付通加密
     * @param bs
     * @return
     */
    public static String bin2hex(byte[] bs) {
        char[] digital = "0123456789ABCDEF".toCharArray();
        StringBuffer sb = new StringBuffer("");
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(digital[bit]);
            bit = bs[i] & 0x0f;
            sb.append(digital[bit]);
        }
        return sb.toString();
    }

    /**
     * 盛付通加密
     * @param str
     * @return
     */
    public static byte[] getByte(String str){
        MessageDigest msgDigest = null;
        byte[] enbyte = null;
        try {
            msgDigest = MessageDigest.getInstance("MD5");
            msgDigest.update(str.getBytes("UTF-8"));
            enbyte = msgDigest.digest();
        } catch (Exception e) {}
        return enbyte;
    }
}

